﻿using LightCAD.Core;
using LightCAD.Core.Elements;
using LightCAD.Drawing.Actions;
using LightCAD.Runtime;
using LightCAD.Runtime.Interface;
using LightCAD.UI.Building;
//using netDxf.Blocks;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Text.RegularExpressions;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace LightCAD.UI
{
    public partial class BuildingSettingWindow : FormBase, IBuildingWindow
    {
        public BuildingSettingWindow()
        {
            InitializeComponent();
        }
        private BuildingAction buildingAction;
        public BuildingSettingWindow(params object[] args) : this()
        {
            if (args != null && args.Length > 0)
            {
                this.buildingAction = (BuildingAction)args[0];
            }
        }
        public string CurrentAction { get; set; }

        public bool IsActive => true;
        public Type WinType => this.GetType();
        public LcBuilding lcBuilding { get; set; }

        private void btnOK_Click(object sender, EventArgs e)
        {

            this.CurrentAction = "OK";
            this.DialogResult = DialogResult.OK;
            this.Close();
        }

        private void BuildingSettingWindow_Load(object sender, EventArgs e)
        {
            InitBuliding();
        }
        public void InitBuliding()
        {
            this.listBuildings.DataSource = null;
            this.listBuildings.DataSource = buildingAction.lcDocument.Buildings;
            this.listBuildings.DisplayMember = "Name";
            if (this.listBuildings.Items.Count > 0)
                this.listBuildings.SelectedIndex = 0;
        }
        private void listBuildings_SelectedIndexChanged(object sender, EventArgs e)
        {
            if (lcBuilding != (LcBuilding)listBuildings.SelectedValue)
            {
                lcBuilding = (LcBuilding)listBuildings.SelectedValue;
                InitdgvLevels();
            }
            if (lcBuilding != null)
            {

                if (lcBuilding.Levels.Count != 0)
                {
                    this.btnInitLevel.Visible = false;
                }
                else
                {
                    this.btnInitLevel.Visible = true;

                }
                var firstLcLevel = lcBuilding.Levels.Where(level => level.Index == 1).FirstOrDefault();
                if (firstLcLevel == null) { return; }
                var floorReferenceVal = firstLcLevel.Elevation;
            }
        }
        private void InitdgvLevels()
        {
            if (lcBuilding == null)
            {
                return;
            }
            this.dgvLevels.DataSource = null;
            this.dgvLevels.AutoGenerateColumns = false;
            this.dgvLevels.DataSource = lcBuilding.Levels;
            FigureUpElevation();
        }
        public void SetLevels()
        {
            lcBuilding.Levels = (LcLevelCollection)this.dgvLevels.DataSource;
        }
        private void btnAddbuilding_Click(object sender, EventArgs e)
        {
            AddBuildingWindow addBuildingWindow = new AddBuildingWindow(buildingAction.lcDocument);
            addBuildingWindow.ShowDialog();
            InitBuliding();
            this.Refresh();
        }

        private void btnInitLevel_Click(object sender, EventArgs e)
        {
            InitLevelsWindow initLevelsWindow = new InitLevelsWindow(buildingAction.lcDocument, lcBuilding);
            initLevelsWindow.ShowDialog();
            InitdgvLevels();
        }

        private void dgvLevels_CellFormatting(object sender, DataGridViewCellFormattingEventArgs e)
        {
            if (e.Value == null) { return; }
            if (e.ColumnIndex == this.dgvLevels.ColumnCount - 1)
            {
                LcLevelType type = (LcLevelType)e.Value;
                switch (type)
                {
                    case LcLevelType.RFloor:
                        e.Value = "屋顶层";
                        break;
                    case LcLevelType.Floor:
                        e.Value = "地上楼层";
                        break;
                    case LcLevelType.BFloor:
                        e.Value = "地下楼层";
                        break;
                    default:
                        break;
                }
            }
        }

        private void btnEditHeight_Click(object sender, EventArgs e)
        {
            SetLevelHeightWindow setLevelHeightWindow = new SetLevelHeightWindow("层高");
            setLevelHeightWindow.ShowDialog();
            double height = setLevelHeightWindow.Height;
            if (setLevelHeightWindow.DialogResult == DialogResult.OK)
            {
                foreach (DataGridViewRow dataGridViewRow in this.dgvLevels.SelectedRows)
                {
                    LcLevel lcLevel = dataGridViewRow.DataBoundItem as LcLevel;
                    lcLevel.Height = height;
                }
                FigureUpElevation();
            }

        }
        public void FigureUpElevation()
        {
            if (lcBuilding == null)
            {
                return;
            }

            var floorLcLevels = lcBuilding.Levels.Where(x => x.Type == LcLevelType.Floor).ToList();
            var rFloorLcLevels = lcBuilding.Levels.Where(x => x.Type == LcLevelType.RFloor).ToList();
            var bFloorLcLevels = lcBuilding.Levels.Where(x => x.Type == LcLevelType.BFloor).ToList();

            foreach (var lcLevel in lcBuilding.Levels)
            {
                //Task.Run(() =>
                //{
                double elevation = floorReferenceVal;
                switch (lcLevel.Type)
                {
                    case LcLevelType.RFloor:
                        foreach (var floorLevel in floorLcLevels)
                        {
                            elevation += floorLevel.Height;
                        }
                        foreach (var rFloorLevle in rFloorLcLevels.Where(x => x.Index < lcLevel.Index))
                        {
                            elevation += rFloorLevle.Height;
                        }
                        break;
                    case LcLevelType.Floor:
                        foreach (var rFloorLevle in floorLcLevels.Where(x => x.Index < lcLevel.Index))
                        {
                            elevation += rFloorLevle.Height;
                        }
                        break;
                    case LcLevelType.BFloor:
                        foreach (var rFloorLevle in bFloorLcLevels.Where(x => x.Index >= lcLevel.Index))
                        {
                            elevation -= rFloorLevle.Height;
                        }
                        break;
                    default:
                        break;
                }
                lcLevel.Elevation = elevation;
                //});
            }
            this.dgvLevels.Refresh();
        }

        private void btnSetFirstHeight_Click(object sender, EventArgs e)
        {
            SetLevelHeightWindow setLevelHeightWindow = new SetLevelHeightWindow("首层");
            setLevelHeightWindow.ShowDialog();
            double height = setLevelHeightWindow.Height;
            if (setLevelHeightWindow.DialogResult == DialogResult.OK)
            {
                var firstLcLevel = lcBuilding.Levels.Where(level => level.Index == 1).FirstOrDefault();
                if (firstLcLevel == null) { return; }
                firstLcLevel.Elevation = height;
                FigureUpElevation();
            }
        }

        private void btnDelbuilding_Click(object sender, EventArgs e)
        {
            var delBuilding = (LcBuilding)listBuildings.SelectedValue;
            if (delBuilding != null)
            {
                if (MessageBox.Show("确定删除单体", "提示", MessageBoxButtons.OKCancel) == DialogResult.OK)
                {
                    buildingAction.lcDocument.Buildings.Remove(delBuilding);
                    InitBuliding();
                }

            }
        }
        private double floorReferenceVal;
        private void btnDelLevel_Click(object sender, EventArgs e)
        {
            if (dgvLevels.SelectedRows.Count == 0)
            {
                return;
            }
            var floorLcLevels = lcBuilding.Levels.Where(x => x.Type == LcLevelType.Floor).ToList();
            var rFloorLcLevels = lcBuilding.Levels.Where(x => x.Type == LcLevelType.RFloor).ToList();
            var bFloorLcLevels = lcBuilding.Levels.Where(x => x.Type == LcLevelType.BFloor).ToList();
            foreach (DataGridViewRow dataGridViewRow in this.dgvLevels.SelectedRows)
            {
                LcLevel lcLevel = dataGridViewRow.DataBoundItem as LcLevel;
                if (lcLevel != null)
                {
                    string r = @"[0-9]+";
                    switch (lcLevel.Type)
                    {
                        case LcLevelType.RFloor:
                            foreach (var floorLcLevel in rFloorLcLevels.Where(x => x.Index > lcLevel.Index))
                            {
                                var result1 = Regex.Match(floorLcLevel.Name, r);
                                double.TryParse(result1.Value, out double count);
                                floorLcLevel.Index--;
                                floorLcLevel.Name = "R" + (count - 1) + "F";
                            }
                            break;
                        case LcLevelType.Floor:
                            foreach (var floorLcLevel in rFloorLcLevels.Where(x => x.Index > lcLevel.Index))
                            {
                                floorLcLevel.Index--;
                            }
                            foreach (var floorLcLevel in floorLcLevels.Where(x => x.Index > lcLevel.Index))
                            {
                                var result1 = Regex.Match(floorLcLevel.Name, r);
                                double.TryParse(result1.Value, out double count);
                                floorLcLevel.Index--;
                                floorLcLevel.Name = (count - 1) + "F";
                            }
                            break;
                        case LcLevelType.BFloor:
                            foreach (var floorLcLevel in bFloorLcLevels.Where(x => x.Index < lcLevel.Index))
                            {
                                var result1 = Regex.Match(floorLcLevel.Name, r);
                                double.TryParse(result1.Value, out double count);
                                floorLcLevel.Index++;
                                floorLcLevel.Name = "B" + (count - 1) + "F";
                            }
                            break;
                        default:
                            break;
                    }
                    lcBuilding.Levels.Remove(lcLevel);
                }
            }
            InitdgvLevels();
        }

        private void btnInsertLevels_Click(object sender, EventArgs e)
        {

        }
    }
}
